package com.baiwei.vpnapi.filter;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.druid.stat.JdbcConnectionStat;
import com.baiwei.vpnapi.entity.VpnUser;
import com.baiwei.vpnapi.handler.MessageSourceHandler;
import com.baiwei.vpnapi.utils.JwtTokenUtil;
import com.baiwei.vpnapi.utils.ResultVoUtils;
import com.baiwei.vpnapi.vo.ResultVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.JwtException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @program: vpnapi
 * @description: jwt 拦截器
 * @author: Mr. Stone
 * @create: 2020-02-25 01:08
 **/

public class JwtTokenFilter extends OncePerRequestFilter {

    private static Log log = LogFactory.getLog(JwtTokenFilter.class);

    @Autowired
    private MessageSourceHandler messageSourceHandler;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    public static final String TOKEN_STRING = "Authorization";
    public static final String LANG_STRING = "language";
    public static final String PLATFORM_STRING = "platform";
    public static final String IP_STRING = "ip";
    public static final String DEVICE_STRING = "device";

    public void apiEntry(HttpServletResponse response) throws IOException {
        Entry entry = null;
        try {
            entry = SphU.entry("vpnapi");
            /*您的业务逻辑 - 开始*/
            /*您的业务逻辑 - 结束*/
        } catch (BlockException e1) {
            /*流控逻辑处理 - 开始*/
            returnServerBusy(response, ResultVoUtils.fail(messageSourceHandler.getMessage("apiServerBusy"), 34768));
            /*流控逻辑处理 - 结束*/
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        //apiEntry(response);
        Entry entry = null;
        try {
            entry = SphU.entry("vpnapi");
            /*您的业务逻辑 - 开始*/
            VpnUser user = null;

            String uri = request.getRequestURI();
            String token = request.getHeader(TOKEN_STRING);
            if (uri.equals("/auth/login") ||
                    uri.equals("/app/advert") ||
                    uri.equals("/app/macos") ||
                    uri.equals("/user/register") ||
                    uri.equals("/pay/commit") ||
                    uri.equals("/pay/success") ||
                    uri.equals("/pay/mpaysuccess") ||
                    uri.equals("/auth/emailcode") ||
                    uri.equals("/auth/smscode") ||
                    uri.equals("/app/push") ||
                    uri.equals("/app/uploadToken") ||
                    uri.startsWith("/app/pushid") ||
                    uri.startsWith("/app/message") ||
                    uri.startsWith("/stat/action") ||
                    uri.equals("/auth/codeauth") ||
                    uri.equals("/pay/commitWeb") ||
                    uri.equals("/auth/authCodeMatch") ||
                    uri.equals("/pay/vipbuy") ||
                    uri.equals("/auth/usercheck")) {
                chain.doFilter(request, response);
            } else {
                if (token == null || token.length() == 0) {
                    returnTokenExpection(response, ResultVoUtils.fail(messageSourceHandler.getMessage("tokenEmpty"), 20000));
                } else {
                    try {
                        System.out.println(token);
                        System.out.println(jwtTokenUtil);
                        if (jwtTokenUtil.isTokenExpired(token)) {
                            returnTokenExpection(response, ResultVoUtils.fail(messageSourceHandler.getMessage("tokenInvalid"), 20000));
                        } else {
                            user = jwtTokenUtil.getVpnUser(token);
                            if (user == null) {
                                returnTokenExpection(response, ResultVoUtils.fail(messageSourceHandler.getMessage("tokenInvalid"), 20000));
                            } else {
                                if(user.getStatus().equals(0)) {
                                    returnTokenExpection(response, ResultVoUtils.fail(messageSourceHandler.getMessage("userInBlackList"), 11111));
                                } else {
                                    chain.doFilter(request, response);
                                }
                            }
                        }
                    } catch (JwtException e) {
                        returnTokenExpection(response, ResultVoUtils.fail(messageSourceHandler.getMessage("tokenInvalid"), 20000));
                    }
                }
            }
            /*您的业务逻辑 - 结束*/
        } catch (BlockException e1) {
            /*流控逻辑处理 - 开始*/
            e1.printStackTrace();
            /*流控逻辑处理 - 结束*/
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }

    private void returnTokenExpection(HttpServletResponse response, ResultVo res) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        ObjectMapper mapper = new ObjectMapper();
        String resJson = mapper.writeValueAsString(res);
        OutputStream out = response.getOutputStream();
        out.write(resJson.getBytes("UTF-8"));
        out.flush();
    }

    private void returnServerBusy(HttpServletResponse response, ResultVo res) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        ObjectMapper mapper = new ObjectMapper();
        String resJson = mapper.writeValueAsString(res);
        OutputStream out = response.getOutputStream();
        out.write(resJson.getBytes("UTF-8"));
        out.flush();
    }

    private void returnObject(HttpServletResponse response, Object info) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        ObjectMapper mapper = new ObjectMapper();
        String resJson = mapper.writeValueAsString(info);
        OutputStream out = response.getOutputStream();
        out.write(resJson.getBytes("UTF-8"));
        out.flush();
    }
}

